package xyz.iguilty.workflow.core.service.impl;

import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceBuilder;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import xyz.iguilty.workflow.constant.ProcessConstants;
import xyz.iguilty.workflow.core.service.AbstractActivity;
import xyz.iguilty.workflow.core.service.WorkFlowActionService;
import xyz.iguilty.workflow.core.service.WorkFlowIdentityService;
import xyz.iguilty.workflow.enums.ProcessAction;
import xyz.iguilty.workflow.model.BusinessModel;
import xyz.iguilty.workflow.model.DealResult;
import xyz.iguilty.workflow.model.SimpleUser;
import xyz.iguilty.workflow.model.TaskForm;
import xyz.iguilty.workflow.utils.ApplicationContextProvider;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

@Service
public class FlowableActionService implements WorkFlowActionService {
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private WorkFlowIdentityService workFlowIdentityService;
    @Autowired
    private TaskService taskService;
    @Override
    public void startProcessInstance(BusinessModel businessModel) {
        Map<String, Object> variables = businessModel.getVariables();
        variables.put(ProcessConstants.FLOWABLE_SKIP_EXPRESSION_ENABLED, true);
        variables.put(ProcessConstants.INITIATOR, "");
        workFlowIdentityService.setAuthenticatedUserId(businessModel.getInitiator());
        String initiator = businessModel.getInitiator();
        SimpleUser user = workFlowIdentityService.getUser(initiator);
        String title = businessModel.getTitle()==null?String.format("%s提交的%s %s",user.getDisplayName(),businessModel.getProcessDefinitionName(),new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())):businessModel.getTitle();
        ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder()
                .processDefinitionKey(businessModel.getProcessDefinitionKey())
                .businessKey(StringUtils.isEmpty(businessModel.getBusinessKey()) ? businessModel.generateBusinessKey() : businessModel.getBusinessKey())
                .variables(variables)
                .name(title)
                .start();
        businessModel.setProcessInstanceId(processInstance.getProcessInstanceId());
    }

    @Override
    public void complete (TaskForm taskForm,String userId) {
        if (StringUtils.isEmpty(taskForm.getTaskId())){
            throw new IllegalArgumentException("请输入任务id");
        }
        Task task = null;
        try {
            task = taskService.createTaskQuery().taskId(taskForm.getTaskId()).taskCandidateOrAssigned(userId).singleResult();
        } catch (Exception ignored) {

        }
        if (task == null) {
            throw new RuntimeException("任务不存在");
        }
        //根据环节id找到对应的业务类
        AbstractActivity activity = ApplicationContextProvider.getBean(task.getTaskDefinitionKey(), AbstractActivity.class);
        if (activity == null) {
            return;
        }
        ProcessAction processAction = ProcessAction.getByActionCode(taskForm.getAction());
        DealResult result = processAction.process(activity, taskForm);
        String taskId = taskForm.getTaskId();

        if (task.getAssignee() == null) {
            taskService.claim(taskId,userId);
        }
        //设置流转变量
        result.getVariables().put(ProcessConstants.CIRCULATION_VARIABLE,processAction.getAction());
        //存储审批意见和附件
        taskService.addComment(taskId,task.getProcessInstanceId(),result.getLogType().getLogType(),taskForm.getComment());
        //保存附件
        if (!CollectionUtils.isEmpty(taskForm.getAttachments())) {
            taskService.createAttachment(null,taskForm.getTaskId(),task.getProcessInstanceId(),"icon.png", org.apache.commons.lang3.StringUtils.join(taskForm.getAttachments(),","),"");
        }
        taskService.complete(taskId,result.getVariables());
    }
}
